#import <Cocoa/Cocoa.h>
#import "header.h"
#import "PSDevice.h"
#import "PSPacket.h"
#import "PSIPPacket.h"
#import "PSARPPacket.h"
#import "PSEthernetPacket.h"
#import "PSFilter.h"
#import "PSError.h"
#import "PSDeviceFinder.h"
#import "PSTCPHeader.h"
#import "PSUDPHeader.h"

@class PSDevice;
@class PSPacket;
@class PSEthernetPacket;
@class PSIPPacket;
@class PSARPPacket;
@class PSFilter;
@class PSError;



// notifications 
extern NSString *const PSReceiveEthernetPacketNotification;
extern NSString *const PSReceiveIPPacketNotification;
extern NSString *const PSReceiveARPPacketNotification;

// Ugly Obj-C to C scope global references
id refToSelf;




/**
 * This protocol forces the delegate object to
 * implement the method which receive packets.
 * It also suggests a way to implement errors
 * callbacks through optional methods.
 */
@protocol SnifferListener

@optional
- (void)receivePacket:(PSPacket *)_packet;
- (void)receiveError:(PSError *)_error;

@end






/**
 * This class is a wrapper for the packet capture
 * process.
 */

// Differanciate Sniffer capture type (All, Ethernet, IP, ARP...)
typedef enum PSCaptureType {
	PSEveryCaptureType			= 0,
	PSEthernetOnlyCaptureType	= 1,
	PSIPOnlyCaptureType			= 2,
	PSARPOnlyCaptureType		= 3
} PSCaptureType;

@interface PSPacketSniffer : NSObject {
	PSDevice *device;
	PSFilter *filter;
	PSCaptureType captureType;
	
	id<SnifferListener> delegate;
	
	int snaplen;
	BOOL promiscuous;
	int timeout;
	
	char errbuf[PCAP_ERRBUF_SIZE];
	BOOL isRunning;
	
	NSNotificationCenter *nc;
}

@property (readwrite, retain)	PSDevice *device;
@property (readwrite, retain)	PSFilter *filter;
@property (readwrite, retain)	id<SnifferListener> delegate;
@property (readwrite)			int snaplen;
@property (readwrite)			BOOL promiscuous;
@property (readwrite)			int timeout;
@property (readwrite)			BOOL isRunning;
@property (readwrite)			PSCaptureType captureType;


/* Create a new Sniffer using notification only */
- (id)initWithDevice:(PSDevice *)_device 
		 captureType:(PSCaptureType)_captureType 
	 promiscuousMode:(BOOL)_promiscuous 
		 withTimeout:(int)_timeout;

/* Create a new Sniffer using notification & delegate */
- (id)initWithDevice:(PSDevice *)_device 
		 captureType:(PSCaptureType)_captureType 
	 promiscuousMode:(BOOL)_promiscuous 
		 withTimeout:(int)_timeout 
			delegate:(id<SnifferListener>)_delegate;


- (void)setFilter:(PSFilter *)_filter;	// Add a filter to the Sniffer
- (void)startCapture;					// Warning ! Note this method starts a capture loop NSThread
- (BOOL)stopCapture;					// Stop the capture loop

- (pcap_t *)handle;						// Do not use.

@end


